package com.jiale.ojsystem.judge;

import com.jiale.ojsystem.model.dto.question.JudgeCase;
import com.jiale.ojsystem.model.entity.QuestionSubmit;

import cn.hutool.json.JSONUtil;
import com.jiale.ojsystem.common.ErrorCode;
import com.jiale.ojsystem.exception.BusinessException;
import com.jiale.ojsystem.model.dto.question.JudgeConfig;
import com.jiale.ojsystem.model.dto.questionsubmit.JudgeInfo;
import com.jiale.ojsystem.model.enums.QuestionSubmitResultEnum;
import com.jiale.ojsystem.service.QuestionSubmitService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 默认判题策略
 */

public class DefaultJudgeStrategy implements JudgeStrategy {

    @Resource
    private QuestionSubmitService questionSubmitService;

    @Override
    public JudgeInfo doJudge(JudgeContext judgeContext) {
        JudgeConfig judgeConfig = judgeContext.getJudgeConfig();
        List<String> outputList = judgeContext.getOutputList();
        List<String> inputList = judgeContext.getInputList();
        JudgeInfo judgeInfo = judgeContext.getJudgeInfo();
        QuestionSubmit questionSubmit = judgeContext.getQuestionSubmit();
        List<JudgeCase> judgeCaseList = judgeContext.getJudgeCaseList();
        long costedTime = judgeContext.getCostedTime();
        long costedMemory = judgeContext.getCostedMemory();
        long timeLimit = judgeConfig.getTimeLimit();
        long memoryLimit = judgeConfig.getMemoryLimit();
        if (inputList.size() != outputList.size()) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR);
        }
        for (int i = 0; i < outputList.size(); i++) {
            if (!outputList.get(i).equals(judgeCaseList.get(i).getOutput())) {
                judgeInfo.setResult(QuestionSubmitResultEnum.WRONG_ANSWER.getValue());
                questionSubmit.setJudgeInfo(JSONUtil.toJsonStr(judgeInfo));
                //更新判题信息
                boolean update3 = questionSubmitService.updateById(questionSubmit);
                if (!update3) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "题目提交状态更新失败");
                }
                return judgeInfo;
            }
        }
        if (costedTime > timeLimit) {
            judgeInfo.setResult(QuestionSubmitResultEnum.TIME_LIMIT_EXCEEDED.getValue());
            questionSubmit.setJudgeInfo(JSONUtil.toJsonStr(judgeInfo));
            //更新判题信息
            boolean update4 = questionSubmitService.updateById(questionSubmit);
            if (!update4) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "题目提交状态更新失败");
            }
            return judgeInfo;
        }
        if (costedMemory > memoryLimit) {
            judgeInfo.setResult(QuestionSubmitResultEnum.MEMORY_LIMIT_EXCEEDED.getValue());
            questionSubmit.setJudgeInfo(JSONUtil.toJsonStr(judgeInfo));
            //更新判题信息
            boolean update5 = questionSubmitService.updateById(questionSubmit);
            if (!update5) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "题目提交状态更新失败");
            }
            return judgeInfo;
        }
        judgeInfo.setResult(QuestionSubmitResultEnum.ACCEPTED.getValue());
        return judgeInfo;
    }
}
